package com.sd.ws;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.HttpKit;
import com.sd.common.constant.WebsocketConstants;
import com.sd.cti.resp.CustomerManager;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.net.URI;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
 * websocket客户端工厂
 */
@Component
public class WebsocketClientFactory {

    @Autowired
    private CustomerManager customerManager;

    @Value("${websocket.gUri}")
    private String g_uri;

    private static final Logger log = LoggerFactory.getLogger(WebsocketClientFactory.class);

    private static final ConcurrentHashMap clients =  new ConcurrentHashMap<String,FlashAgentX>();
    private static final ConcurrentHashMap tokenMap =  new ConcurrentHashMap<String,FlashAgentX>();

    /**
     * 获取FlashAgentX
     * @param agentId 坐席id
     * @return
     */
    public FlashAgentX get(String agentId){
        FlashAgentX flashAgentX = (FlashAgentX)clients.get(agentId);
        if(flashAgentX != null){
            if(flashAgentX.getSocket() == null){
                flashAgentX = createWebSocketClient(agentId);
            }else {
                WebSocketClient socket = flashAgentX.getSocket();
                if(!socket.isOpen()){
                   if(socket.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)){
                       try {
                           socket.connect();
                       } catch (IllegalStateException e) {
                           e.printStackTrace();
                       }
                   }else if (socket.getReadyState().equals(ReadyState.CLOSING) || socket.getReadyState().equals(ReadyState.CLOSED)) {
                       socket.reconnect();
                   }
                }
                flashAgentX.setSocket(socket);
            }
        }
        return flashAgentX;
    }

    private FlashAgentX createWebSocketClient(String agentId){
        try {
            FlashAgentX flashAgentX = (FlashAgentX)clients.get(agentId);
            if(flashAgentX == null){
                return null;
            }
            String g_WSUrl = g_uri + flashAgentX.getG_TokenId() + "/" + agentId;
            System.out.println("g_WSUrl:"+g_WSUrl);
            WebSocketClient webSocketClient = webSocketClient(g_WSUrl,agentId);
            webSocketClient.connect();
            flashAgentX.setSocket(webSocketClient);
            clients.put(agentId,flashAgentX);
            return flashAgentX;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 创建FlashAgent
     * @param agentId 坐席id
     * @param entId 企业id
     * @return
     */
    public FlashAgentX createFlashAgentX(String agentId,String entId,String extNum){
        try {
            FlashAgentX flashAgentX = (FlashAgentX)clients.get(agentId);
            if(flashAgentX != null){
                return flashAgentX;
            }
            String g_TokenId = UUID.randomUUID().toString();
            // String g_OptId = agentId;
            String g_WSUrl = g_uri + g_TokenId + "/" + agentId;
            System.out.println("g_WSUrl:"+g_WSUrl);
            WebSocketClient webSocketClient = webSocketClient(g_WSUrl,agentId);
            webSocketClient.connect();
            flashAgentX = new FlashAgentX(webSocketClient, agentId, entId, g_TokenId,extNum);
            clients.put(agentId,flashAgentX);
            tokenMap.put(g_TokenId,flashAgentX);
            return flashAgentX;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 创建websocket客户端
     * @param g_WSUrl 客户端url地址
     * @return
     * @throws Exception
     */
    private WebSocketClient webSocketClient(String g_WSUrl,String agentId) throws Exception{
        MyWebSocketClient webSocketClient = new MyWebSocketClient(new URI(g_WSUrl),agentId){

            @Override
            public void onOpen(ServerHandshake serverHandshake) {
                log.info("[websocket] 连接成功:onOpen serverHandshake:[{}]",serverHandshake);
                monitor(WebsocketConstants.EventTypeEnum.onOpen.getValue(),null,this.getAgentId());
            }

            @Override
            public void onMessage(String message) {
                log.info("[websocket] 调试信息---------->recive:[{}]",message);
                monitor(WebsocketConstants.EventTypeEnum.onMessage.getValue(),null,this.getAgentId());
               /* if (message.indexOf("pong")>=0) { //心跳
                    return;
                }
                sendMessageToCustomer(message);*/
            }

            @Override
            public void onClose(int i, String s, boolean b) {
                log.info("[websocket] 退出连接:onClose i:[{}] s:[{}] b:[{}]",i,s,b);
                monitor(WebsocketConstants.EventTypeEnum.onClose.getValue(),null,this.getAgentId());
            }

            @Override
            public void onError(Exception ex) {
                log.info("[websocket] 连接错误:onError ex:[{}]",ex.getMessage());
                monitor(WebsocketConstants.EventTypeEnum.onError.getValue(),null,this.getAgentId());
            }
        };
        return webSocketClient;
    }

    /**
     * 监控事件变化
     * @param event 事件
     * @param message 消息
     * @param agentId 坐席id
     */
    public void monitor(String event,String message,String agentId){
        try {
            log.info("monitor 触发: event:[{}] message:[{}] agentId:[{}]",event,message,agentId);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    /**
     * 根据不同返回结果执行不同操作
     * @param message
     */
    public void sendMessageToCustomer(String message){
        String servicecode = getValue("head", "servicecode", message);
        String tokenId = getValue("body", "tokenid", message);
        FlashAgentX flashAgentX = (FlashAgentX)tokenMap.get(tokenId);
        switch (servicecode){
            case "1001"://签入
                customerManager.respLogin(flashAgentX.getG_OptId(),flashAgentX.getG_extNum(),flashAgentX.getG_TokenId());
                break;
            default:
                break;
        }
    }

    /**
     * 获取json字符串中head或者body里面的值
     * @param headOrBody  取值"head" 和 "body"
     * @param key 目标key
     * @param jsonStr json字符串
     * @return
     */
    private String getValue(String headOrBody,String key,String jsonStr){
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        JSONObject target = null;
        if("body".equals(headOrBody)){
            target = jsonObject.getJSONObject("body");
        }else if("head".equals(headOrBody)){
            target = jsonObject.getJSONObject("head");
        }
        return String.valueOf(target.get(key));
    }


    public static void main(String[] args) {
         String message = "123321";
         log.info("[websocket] 调试信息---------->recive:[{}]",message);
         String jsonStr = "{\"head\":{\"errcode\":\"0\",\"servicecode\":\"1001\",\"errmsg\":\"操作成功\"},\"body\":{\"tokenid\":\"f28fa527-2c33-466d-8a3b-8f9dbab192b4\",\"hostmillis\":1598948922432}}";
         JSONObject jsonObject = JSONObject.parseObject(jsonStr);
         JSONObject head = jsonObject.getJSONObject("head");
         JSONObject body = jsonObject.getJSONObject("body");
         System.out.println("head:"+head);
         System.out.println("body:"+body);
         String tokenid = String.valueOf(body.get("tokenid"));
         System.out.println("tokenid:"+tokenid);

        /*JSONObject jsonObject = new JSONObject();
        JSONObject head = jsonObject.getJSONObject("head");
        JSONObject body = jsonObject.getJSONObject("body");*/
        //System.out.println("head:"+head);
        //System.out.println("body:"+body);
    }
}
